package com.example.pengxiangedupay.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.example.pengxiangedupay.common.utils.R;
import com.example.pengxiangedupay.entity.FeeStuPaidEntity;
import com.example.pengxiangedupay.entity.OrderInfoEntity;
import com.example.pengxiangedupay.service.AlipayService;
import com.example.pengxiangedupay.service.FeeStuPaidService;
import com.example.pengxiangedupay.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

@Controller
@Slf4j
@RequestMapping("/app")
public class AppPayController {

    @Autowired
    FeeStuPaidService feeStuPaidService;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    AlipayClient alipayClient;
    @Autowired
    AlipayService alipayService;
    @Autowired
    Environment config;

    @ResponseBody
    @PostMapping("/pay/tradePagePay")
    public R tradePagePay(HttpSession session,Long feeId,BigDecimal money,@RequestBody String feePayList){

        if(feeId == null){
            return R.error("缴费信息有误，请重新选择提交");
        }
        FeeStuPaidEntity feeStuPaid = feeStuPaidService.getById(feeId);
        if(feeStuPaid == null || "已缴清".equals(feeStuPaid.getFeeStatus())){
            return R.error("缴费信息有误或已缴清，请重新选择提交");
        }
        System.out.println(feePayList);
        JSONObject jsonObjectOuter = JSONObject.parseObject(feePayList);
        Object resultObject= jsonObjectOuter.get("feePayList");
        String feePayJson = JSON.toJSONString(resultObject);
        //        把feeId 放在session中
//        session.setAttribute("feeId",feeId);
//        session.setAttribute("feePayList",resultObject);
        String formStr = alipayService.tradeCreate(feeId,feePayJson);
        return R.ok().put("formStr",formStr);
    }

    @ResponseBody
    @PostMapping("/pay/beforePay")
    public String beforePay(HttpSession session,Long feeId,BigDecimal money,@RequestBody String feePayList){
        if(feeId == null){
            return "缴费信息有误，请重新选择提交";
        }
        FeeStuPaidEntity feeStuPaid = feeStuPaidService.getById(feeId);
        if(feeStuPaid == null || "已缴清".equals(feeStuPaid.getFeeStatus())){
            return "缴费信息有误或已缴清，请重新选择提交";
        }
        String moneyString = money.toString();

        System.out.println(feePayList);
        JSONObject jsonObjectOuter = JSONObject.parseObject(feePayList);
        Object resultObject= jsonObjectOuter.get("feePayList");
        //        把feeId 放在session中
        session.setAttribute("feeId",feeId);
        session.setAttribute("feePayList",resultObject);

//        return "/api/app/pay/alipay?dona_money="+moneyString;

        return "/api/app/pay/tradePagePay?productId="+feeId;

    }

    @PostMapping("/trade/notify")
    public String tradeNotify(@RequestParam Map<String, String> params){

        log.info("支付通知正在执行");
        log.info("通知参数 ===> {}", params);

        String result = "failure";

        try {
            //异步通知验签
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    config.getProperty("alipay.alipay-public-key"),
                    AlipayConstants.CHARSET_UTF8,
                    AlipayConstants.SIGN_TYPE_RSA2); //调用SDK验证签名

            if(!signVerified){
                //验签失败则记录异常日志，并在response中返回failure.
                log.error("支付成功异步通知验签失败！");
                return result;
            }

            // 验签成功后
            log.info("支付成功异步通知验签成功！");

            //按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，
            //1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号
            String outTradeNo = params.get("out_trade_no");
            OrderInfoEntity order = orderInfoService.getOrderByOrderNo(outTradeNo);
            if(order == null){
                log.error("订单不存在");
                return result;
            }

            //2 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）
            String totalAmount = params.get("total_amount");
            BigDecimal totalAmountInt = new BigDecimal(totalAmount);
            if(totalAmountInt.compareTo(order.getTotalFee()) != 0){
                log.error("金额校验失败");
                return result;
            }

            //3 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方
            String sellerId = params.get("seller_id");
            String sellerIdProperty = config.getProperty("alipay.seller-id");
            if(!sellerId.equals(sellerIdProperty)){
                log.error("商家pid校验失败");
                return result;
            }

            //4 验证 app_id 是否为该商户本身
            String appId = params.get("app_id");
            String appIdProperty = config.getProperty("alipay.app-id");
            if(!appId.equals(appIdProperty)){
                log.error("appid校验失败");
                return result;
            }

            //在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS时，
            // 支付宝才会认定为买家付款成功。
            String tradeStatus = params.get("trade_status");
            if(!"TRADE_SUCCESS".equals(tradeStatus)){
                log.error("支付未成功");
                return result;
            }
            String idAndPay = params.get("body");
            JSONObject jsonObject = JSON.parseObject(idAndPay);
            String id = jsonObject.getString("id");
            String feeJson = jsonObject.getString("fee_json");
//            String feeId = (String) jsonObject.get("product_id");
//            String feePayJson  = (String) jsonObject.get("fee_json");
            params.put("feeId",id);
            params.put("feePayJson",feeJson);
            //处理业务 修改订单状态 记录支付日志
            boolean changeStatus = alipayService.processOrder(params);
            if(!changeStatus){
                return result;
            }
            //校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            result = "success";
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

}